package cn.touna.jss.modules.third.dianhuabang;

import cn.touna.jss.common.properties.disconf.DianHuaBangProperties;
import cn.touna.jss.common.util.ValidUtil;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.callback.entity.DianHuaBangCallback;
import cn.touna.jss.modules.third.dianhuabang.entity.DianHuaBangRequestDto;
import cn.touna.jss.modules.third.dianhuabang.entity.DianHuaBangRequestEntity;
import cn.touna.jss.modules.third.dianhuabang.entity.DianHuaBangResponseEntity;
import cn.touna.jss.modules.third.dianhuabang.entity.CallLogEntity;
import cn.touna.jss.modules.third.dianhuabang.service.IDianHuaBangService;
import cn.touna.jss.modules.third.dianhuabang.service.impl.DianHuaBangServiceImpl;
import cn.touna.risk.api.domain.Response;
import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.touna.loan.log.service.TracerContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 电话邦催收
 * 2018-12-27
 */
@Service
public class DianHuaBangService {

    private static final Logger LOG = LoggerFactory.getLogger(DianHuaBangService.class);

    @Autowired
    private DianHuaBangProperties dianHuaBangProperties;

    @Autowired
    private IDianHuaBangService dianHuaBangService;

    /**
     * 催收请求队列
     */
    private static final BlockingQueue<RetryRequest> DHB_REQUEST_QUEUE = new ArrayBlockingQueue<>(256);

    @PostConstruct
    public void init() {
        new JxlCallbackThread().start();
    }

    /**
     * 1. 聚信立
     * 2. 催收
     *
     * @param request
     * @return
     */
    @ApiMapping(value = "dianhuabang.cuishou", desc = "电话帮.催收")
    public Response cuishou(DianHuaBangRequestEntity request) {
        Response response = ValidUtil.valid(request);
        if (response != null) {
            return response;
        }
        response = new Response();
        RetryRequest retryRequest = new RetryRequest();
        retryRequest.setRequest(request);
        retryRequest.setSleep(dianHuaBangProperties.getInterval());
        retryRequest.setRetryCount(new AtomicInteger(dianHuaBangProperties.getRetryCount()));
        DHB_REQUEST_QUEUE.offer(retryRequest);
        return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, null);
    }

    class JxlCallbackThread extends Thread {

        @Override
        public void run() {
            try {
                while (true) {
                    RetryRequest retryRequest = DHB_REQUEST_QUEUE.take();
                    DianHuaBangRequestEntity request = retryRequest.getRequest();
                    AtomicInteger retryCount = retryRequest.getRetryCount();

                    //1. 获取通话详情
                    Response response = dianHuaBangService.callLogList(request);
                    if (response.getCode().equals(DianHuaBangServiceImpl.DHB_ERROR_CODE)) {
                        //解析json出错
                        LOG.info("获取通话详情出错:{}", response.getMsg());
                        continue;
                    }
                    List<CallLogEntity> callLogList = (List<CallLogEntity>) response.getData();
                    if (response.getCode().equals(DianHuaBangServiceImpl.DHB_RETRY_CODE) || CollectionUtils.isEmpty(callLogList)) {
                        //未获取到数据
                        if (retryCount.decrementAndGet() <= 0) {
                            continue;
                        } else {
                            DHB_REQUEST_QUEUE.offer(retryRequest);
                            sleep(retryRequest.getSleep());
                            continue;
                        }
                    }

                    if (callLogList.size() < 20 || callLogList.size() > 20000) {
                        LOG.error("通话记录必须在20~20000之间");
                        continue;
                    }

                    request.setCall_log(callLogList);
                    //2. 生成签名
                    Map<String, Object> signature = dianHuaBangService.signature(dianHuaBangProperties.getApikey(), dianHuaBangProperties.getAppsecret(), null, null);

                    //3. 生成请求参数
                    DianHuaBangRequestDto requestDto = new DianHuaBangRequestDto();
                    requestDto.setName(request.getName());
                    requestDto.setIdnum(request.getIdCard());
                    requestDto.setTel(request.getMobile());
                    requestDto.setUid(TracerContextUtil.getTraceId());
                    requestDto.setTime(request.getTime());
                    requestDto.setTime_type(request.getTime_type());
                    requestDto.setCall_log(request.getCall_log());
                    String params = JSON.toJSONString(requestDto);

                    //4. 发送请求
                    String url = dianHuaBangService.signUrl(dianHuaBangProperties.getUrl(), signature);
                    DianHuaBangResponseEntity responseEntity = dianHuaBangService.cuishou(url, params);
                    LOG.info("电话帮催收响应结果:{}", responseEntity);

                    //5. 处理响应结果
                    if (Objects.equals(responseEntity.getStatus(), "0")) {
                        //成功
                        DianHuaBangCallback callback = new DianHuaBangCallback();
                        callback.setName(request.getName());
                        callback.setIdCard(request.getIdCard());
                        callback.setMobile(request.getMobile());
                        callback.setUid(requestDto.getUid());
                        //电话帮的通话详情太大，忽略储存
                        requestDto.setCall_log(null);
                        callback.setRequestParams(JSON.toJSONString(requestDto));
                        callback.setStatus((byte) 1);
                        JSONObject data = (JSONObject) responseEntity.getData();
                        callback.setSid(data.getString("sid"));//mysql sid=1
                        dianHuaBangService.saveRequestHistory(callback);
                        LOG.info("电话帮催收调用成功:{}", data);
                    } else {
                        //失败
                        LOG.info("电话帮催收调用失败status:{},msg:{}", responseEntity.getStatus(), responseEntity.getMsg());
                    }
                }
            } catch (Exception e) {
                LOG.error("催收调用异常:{}", e);
            }
        }
    }

    static class RetryRequest {
        private DianHuaBangRequestEntity request;
        private AtomicInteger retryCount;
        private int sleep;

        public DianHuaBangRequestEntity getRequest() {
            return request;
        }

        public void setRequest(DianHuaBangRequestEntity request) {
            this.request = request;
        }

        public AtomicInteger getRetryCount() {
            return retryCount;
        }

        public void setRetryCount(AtomicInteger retryCount) {
            this.retryCount = retryCount;
        }

        public int getSleep() {
            return sleep;
        }

        public void setSleep(int sleep) {
            this.sleep = sleep;
        }
    }
}
